<script lang="ts" setup>
import type { Nullable } from '@vben/types';

import type { TreeActionType, TreeItem } from '#/components/tree';

import { ref, unref } from 'vue';

import { useVbenModal } from '@vben/common-ui';

import { Tag } from 'ant-design-vue';

import { DefResourceApi } from '#/api';
import { BasicTree } from '#/components/tree';
import { ResourceTypeEnum } from '#/enums/system';
import { useMessage } from '#/hooks/web/useMessage';
import { $t } from '#/locales';
import { getResourceTagColor } from '#/utils/color';
import { eachTree } from '#/utils/helper/treeHelper';

interface Emits {
  (e: 'success'): void;
}

defineOptions({
  name: '移动资源',
  inheritAttrs: false,
});
const emit = defineEmits<Emits>();

const treeRef = ref<Nullable<TreeActionType>>(null);

const treeLoading = ref<boolean>(false);
const treeData = ref<TreeItem[]>([]);
const currentRef = ref<any>({});
const titleRef = ref<string>('');

const { createMessage, createConfirm } = useMessage();

function getTree() {
  const tree = unref(treeRef);
  if (!tree) {
    throw new Error('树结构加载失败,请刷新页面');
  }
  return tree;
}

const [Modal, modalApi] = useVbenModal({
  async onOpened() {
    const data = modalApi.getData();
    currentRef.value = data?.current;
    getTree()?.setSelectedKeys([]);

    titleRef.value = `${$t(`common.title.move`)}：【${data?.current.name}】`;

    try {
      treeLoading.value = true;

      treeData.value = (await DefResourceApi.tree({
        applicationId: data.applicationId,
      })) as unknown as TreeItem[];

      const current = unref(currentRef);
      eachTree(
        treeData.value,
        (item, parent) => {
          item.key = item.id;

          item.keyLinks = [...(parent.keyLinks || []), item.id];
          item.disabled =
            item.id === current.parentId ||
            item.id === current.id ||
            item.treePath.includes(`/${current.id}/`);
          if (item.id === current.parentId) {
            item.title = `${item.name}  (不能移动到他的父节点)`;
          } else if (item.id === current.id) {
            item.title = `${item.name}  (不能移动到他自己下)`;
          } else if (item.treePath.includes(`/${current.id}/`)) {
            item.title = `${item.name}  (不能移动到他的子孙节点)`;
          } else {
            item.title = item.name;
          }

          item.slots = { titleBefore: 'titleBefore' };
          return item;
        },
        {},
      );
    } finally {
      treeLoading.value = false;
    }

    setTimeout(() => {
      getTree().filterByLevel(2);
    }, 0);
  },
  async onConfirm() {
    await handleSubmit(false);
  },
});

async function handleSubmit(isMoveRoot = false) {
  try {
    modalApi.setState({ loading: true, confirmLoading: true });
    // 当前节点
    const current = unref(currentRef);

    const id = current.id;
    if (!id) {
      createMessage.error('请选择需要移动的节点');
      return;
    }
    let title = `确定要将【${current.name}】移动到【根节点】`;
    const keys = getTree()?.getSelectedKeys();
    // 父节点id
    let parentId = keys?.[0] as string;
    // 父节点
    const parentNode = getTree()?.getSelectedNode(parentId);

    if (isMoveRoot) {
      parentId = '';
      if (
        [
          ResourceTypeEnum.BUTTON,
          ResourceTypeEnum.DATA,
          ResourceTypeEnum.FIELD,
        ].includes(current?.resourceType)
      ) {
        createMessage.warning(`当前节点【${current.name}】不能挂载在根节点`);
        return;
      }
    } else {
      switch (current.resourceType) {
        case ResourceTypeEnum.BUTTON: {
          break;
        }
        case ResourceTypeEnum.DATA: {
          if (
            ![ResourceTypeEnum.BUTTON, ResourceTypeEnum.MENU].includes(
              parentNode?.resourceType,
            )
          ) {
            createMessage.warning('数据只能挂载在菜单或按钮下');
            return;
          }
          break;
        }
        case ResourceTypeEnum.FIELD: {
          if (
            ![ResourceTypeEnum.BUTTON, ResourceTypeEnum.MENU].includes(
              parentNode?.resourceType,
            )
          ) {
            createMessage.warning('字段只能挂载在菜单或按钮下');
            return;
          }
          break;
        }
        default: {
          if (![ResourceTypeEnum.MENU].includes(parentNode?.resourceType)) {
            createMessage.warning('菜单只能挂载在菜单下级');
            return;
          }
          if (parentNode?.isHidden && !current?.isHidden) {
            createMessage.warning('菜单不能挂载在隐藏菜单下级');
            return;
          }
          break;
        }
      }

      let node = {} as TreeItem;
      if (keys !== null) {
        node = getTree()?.getSelectedNode(parentId) as TreeItem;
      }
      title = `确定要将【${current.name}】移动到【${node ? node?.name : '根节点'}】`;
    }

    createConfirm({
      iconType: 'warning',
      content: title,
      onOk: async () => {
        try {
          await DefResourceApi.move(current.id, parentId);
          createMessage.success('移动成功');
          modalApi.close();
          emit('success');
        } catch {}
      },
    });
  } finally {
    modalApi.setState({ loading: false, confirmLoading: false });
  }
}

function handleMoveToRoot() {
  handleSubmit(true);
}
defineExpose(modalApi);
</script>
<template>
  <Modal class="w-[50%]" title="移动" confirm-text="移动到选中节点">
    <template #center-footer>
      <a-button @click="handleMoveToRoot"> 移动到根节点</a-button>
    </template>

    <BasicTree
      ref="treeRef"
      :click-row-to-expand="false"
      :loading="treeLoading"
      :title="titleRef"
      :tree-data="treeData"
      check-strictly
      highlight
      search
      toolbar
    >
      <template #titleBefore="item">
        <template v-if="item.echoMap?.resourceType">
          <Tag :color="getResourceTagColor(item?.resourceType, item.isHidden)">
            {{ item.echoMap?.resourceType }}
          </Tag>
        </template>
      </template>
    </BasicTree>
  </Modal>
</template>
<style scoped lang="less"></style>
